package net.melon.product.inst.struts2;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.esj.basic.core.view.tools.ActionContext;
import net.esj.basic.exception.MelonException;
import net.esj.basic.utils.Assert;
import net.esj.basic.utils.CollectionUtils;
import net.esj.basic.utils.StringUtils;
import net.esj.basic.utils.Validators;
import net.esj.basic.utils.view.BaseJsonMessage.MessageLevel;
import net.esj.basic.view.AbstractPluginPageAction;
import net.melon.product.inst.service.BrandService;
import net.melon.product.inst.service.ProductService;
import net.melon.product.inst.service.SpecificationsService;
import net.melon.product.inst.service.TypeService;
import net.melon.product.inst.service.impl.ClassifyCacheProxy;
import net.melon.product.inst.service.impl.SpecificationsValueCacheProxy;
import net.melon.product.pojo.Product;
import net.melon.product.pojo.Product.PRODUCT_ENABLE;
import net.melon.product.pojo.ProductAttribute;
import net.melon.product.pojo.ProductBrand;
import net.melon.product.pojo.ProductClassify;
import net.melon.product.pojo.ProductSku;
import net.melon.product.pojo.ProductSpecificationsLink;
import net.melon.product.pojo.ProductSpecificationsValue;
import net.melon.product.pojo.ProductTypeBrandLink;
import net.melon.product.pojo.ProductTypeSpecificationsLink;
import net.melon.product.pojo.dto.ProductImageDto;
import net.melon.product.pojo.dto.ProductSpecificationsValueDto;
import net.melon.uploader.ErrorInfo;
import net.melon.uploader.Uploader;
import net.melon.uploader.exception.UploadRuntimeException;
import net.melon.uploader.pojo.FileUpload;
import net.melon.uploader.service.FileNameRule;
import net.melon.uploader.service.PathRule;
import net.melon.uploader.service.impl.DateSplitPathRule;
import net.melon.uploader.service.impl.RandomFileNameRule;

public class ProductAction extends AbstractPluginPageAction<Product, Product>{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1476375565418554183L;
	
	public static final String PRODUCT_ATTRIBUTE_KEY ="_product_attribute_"; 
	
	public static final String PRODUCT_SKU_KEY ="_product_sku_"; 
	
	public static final String PRODUCT_SPECIFICATION_KEY ="_product_specifications_"; 

	private Long classifyId;
	
	@Resource
	private BrandService brandService;
	
	@Resource
	private TypeService typeService;
	
	@Resource
	private ClassifyCacheProxy classifyCacheProxy;
	
	@Resource
	private SpecificationsValueCacheProxy specificationsValueCacheProxy;
	
	@Resource
	private SpecificationsService specificationsService;
	
	@Resource
	private ProductService productService;
	
	private List<String> picnames;
	
	private List<ProductSku> productSkus = new ArrayList<ProductSku>();
	
	private int state;
	
	@Override
	protected void doQueryPage() {
		//pagination.getQueryBuilder().eq("state", 1);
		//super.doQueryPage();
		pagination = productService.productPage(pagination);
	}

	@Override
	protected void doAdd() throws Exception {
		specificationsList();
		productService.addProduct(entity,picnames);
	}
	
	@Override
	protected void doDelete() throws Exception {
		productService.deleteProduct(deletes);
	}
	
	public List<ProductSpecificationsValue> getColors(){
		List<ProductSpecificationsValue> specifications = specificationsValueCacheProxy.getSortList();
		List<ProductSpecificationsValue> list = new ArrayList<ProductSpecificationsValue>();
		for(ProductSpecificationsValue ps : specifications){
			if(ps.getSpecifications().getId()==1){
				list.add(ps);
			}
		}
		return list;
	}
	
	public List<ProductSpecificationsValue> getConfigures(){
		List<ProductSpecificationsValue> specifications = specificationsValueCacheProxy.getSortList();
		List<ProductSpecificationsValue> list = new ArrayList<ProductSpecificationsValue>();
		for(ProductSpecificationsValue ps : specifications){
			if(ps.getSpecifications().getId()==2){
				list.add(ps);
			}
		}
		return list;
	}
	
	public List<ProductSpecificationsValue> getParameters(){
		List<ProductSpecificationsValue> specifications = specificationsValueCacheProxy.getSortList();
		List<ProductSpecificationsValue> list = new ArrayList<ProductSpecificationsValue>();
		for(ProductSpecificationsValue ps : specifications){
			if(ps.getSpecifications().getId()==3){
				list.add(ps);
			}
		}
		return list;
	}
	
	public String productSelect(){
		return SUCCESS;
	}
	
	@Override
	protected void doGetEntity() {
		entity = productService.getProduct(id, false, false, false, true,true); 
	}
	
	@Override
	protected void doUpdate() throws Exception {
		specificationsList();
		productService.updateProduct(entity,picnames);
	}
	
	public String stock(){
		productSkus = productService.getProductSkuList(id);
		return SUCCESS;
	}
	
	public void editStock(){
		try {
			List<ProductSku> productSkus = returnSkuList();
			if(Validators.isEmpty(productSkus) || !StringUtils.hasText(id)){
				writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), "参数错误，请查看", MessageLevel.ERROR, "html");
			}else{
				productService.editStock(id,productSkus);
				writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), addSuccMsg(), MessageLevel.INFO, "html");
			}
		} catch (Exception e) {
			e.printStackTrace();
			writeError(e.getMessage());
		}
	}
	
	public void marketEnable(){
		try {
			if(!StringUtils.hasText(id)){
				writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), "参数错误，请查看", MessageLevel.ERROR, "html");
			}else{
				productService.marketEnable(id,state);
				writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), addSuccMsg(), MessageLevel.INFO, "html");
			}
		} catch (MelonException e) {
			writeBaseJsonMessage(getText(SYSTEM_MESSAGE_TITLE,""), addFailMsg(e), MessageLevel.ERROR, "html");
		}catch (Exception e) {
			e.printStackTrace();
			writeError(e.getMessage());
		}
	}
	
	public PRODUCT_ENABLE[] getProductEnables(){
		return Product.PRODUCT_ENABLE.values();
	}
	public void deleteImage(){
		productService.deleteImage(id);
	}
	
	public List<ProductBrand> getBrands(){
		try {
			ProductClassify classify = classifyCacheProxy.getClassify(classifyId);
			Assert.notNull(classify);
			List<ProductTypeBrandLink> list = typeService.existBrandLinks(classify.getType().getId());
			List<ProductBrand> brands = new ArrayList<ProductBrand>();
			for(ProductTypeBrandLink link : list){
				brands.add(link.getBrand());
			}
			return brands;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public List<ProductAttribute> getAttributes(){
		try {
			ProductClassify classify = classifyCacheProxy.getClassify(classifyId);
			Assert.notNull(classify);
			List<ProductAttribute> list = typeService.getAttributeListByTypeId(classify.getType().getId());
			return list;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public void getProductSpecificationsValueDtos(){
		try {
			ProductClassify classify = classifyCacheProxy.getClassify(classifyId);
			Assert.notNull(classify);
			List<ProductTypeSpecificationsLink> list = typeService.exitSpecificationsLinks(classify.getType().getId());
			List<ProductSpecificationsValueDto> dtoList = new ArrayList<ProductSpecificationsValueDto>();
			for(ProductTypeSpecificationsLink link : list){
				ProductSpecificationsValueDto dto = specificationsService.getValueDto(link.getSpecifications().getId());
				dtoList.add(dto);
			}
			writeJson(dtoList);
		} catch (Exception e) {
			e.printStackTrace();
			writeError(e);
		}
	}
	
	private PathRule pathRule = new DateSplitPathRule();
	
	private FileNameRule fileNameRule = new RandomFileNameRule();
	
	Uploader uploader = new Uploader(pathRule, fileNameRule, Product.ICON_SUB_DIR);
	
	public void upload() throws Exception{
		try{
			uploader.setAllowFiles(new String[]{".jpg",".png",".gif",".jpeg",".bmp"});
			List<FileUpload> list = uploader.upload(getRequest());
			if(!CollectionUtils.isEmpty(list)){
				FileUpload fu = list.get(0);
				writeString("{'state':'"+ErrorInfo.SUCCESS+"','url':'"+fu.getUrl()+"','original':'"+fu.getOriginal()+"'}");
			}else{
				writeString("{state:'"+ErrorInfo.UNKNOW+"'}");
			}
		}catch(UploadRuntimeException e){
			writeString("{state:'"+e.getMessage()+"'}");
		}
	}
	
	public void imageManager(){
		String[] files = uploader.getDownFiles();
		writeString(StringUtils.join(files, "ue_separate_ue"));
	}
	
	public String getDownloadUrl(){
		return Uploader.getDownUrl(Product.ICON_SUB_DIR);
	}
	
	public String getDirUrl(){
		String baseUrl = Product.ICON_SUB_DIR;
		return baseUrl;
	}
	
	public void getProductImageDto(){
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if(StringUtils.hasText(id)){
				ProductImageDto dto = productService.getProductImageDto(id);
				map.put("suc", 1);
				map.put("dto", dto);
			}else{
				map.put("suc", 0);
			}
		} catch (Exception e) {
			map.put("suc", -1);
			e.printStackTrace();
		}
		writeJson(map);
	}
	
	private void specificationsList(){
		Enumeration enumeration = getRequest().getParameterNames();
		while (enumeration.hasMoreElements()) {
			String name = (String) enumeration.nextElement();
			if (name.startsWith(PRODUCT_SPECIFICATION_KEY)) {
				String[] values = ActionContext.getRequest().getParameterValues(name);
				if(Validators.isEmpty(values)){
					continue;
				}
				name = name.substring(PRODUCT_SPECIFICATION_KEY.length());
				String[] names = name.split("_");
				for(String value : values){
					entity.getSpecifications().add(new ProductSpecificationsLink(Long.valueOf(names[0]), Long.valueOf(names[1]),value));
				}
			}
		}
	}
	
	private List<ProductSku> returnSkuList(){
		Enumeration enumeration = getRequest().getParameterNames();
		List<ProductSku> productSkus = new ArrayList<ProductSku>();
		while (enumeration.hasMoreElements()) {
			String name = (String) enumeration.nextElement();
			if (name.startsWith(PRODUCT_SKU_KEY)) {
				String[] values = ActionContext.getRequest().getParameterValues(name);
				if(values.length!=3){
					return null;
				}
				ProductSku sku = new ProductSku();
				sku.setId(Long.valueOf(values[0]));
				sku.setPrice(Double.valueOf(values[1]));
				productSkus.add(sku);
			}
		}
		return productSkus;
	}
	
	public Long getClassifyId() {
		return classifyId;
	}

	public void setClassifyId(Long classifyId) {
		this.classifyId = classifyId;
	}

	public List<String> getPicnames() {
		return picnames;
	}

	public void setPicnames(List<String> picnames) {
		this.picnames = picnames;
	}

	public Product getEntity(){
		return entity;
	}
	
	public void setEntity(Product entity){
		this.entity = entity;
	}

	public List<ProductSku> getProductSkus() {
		return productSkus;
	}

	public void setProductSkus(List<ProductSku> productSkus) {
		this.productSkus = productSkus;
	}

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}
	
}
